//
//  MJGridView.m
//  MJGridView
//
//  Created by Jarvis on 2023/9/8.
//

#import "MJGridView.h"
#import <objc/runtime.h>

@interface NSArray<ObjectType> (Filter)
- (NSArray *)filter:(BOOL(^)(ObjectType obj))block;
@end
@implementation NSArray (Filter)
- (NSArray *)filter:(BOOL(^)(id obj))block {
    NSMutableArray *arr = [NSMutableArray array];
    for (id obj in self) {
        if (block(obj)) {
            [arr addObject:obj];
        }
    }
    return arr.copy;
}
@end

@interface UIView (Identifier)
@property (nonatomic, copy ) NSString *identifier;
@end
@implementation UIView (Identifier)
- (NSString *)identifier {
    return objc_getAssociatedObject(self, _cmd);
}
- (void)setIdentifier:(NSString *)identifier {
    objc_setAssociatedObject(self, @selector(identifier), identifier, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end



@interface MJGridView ()
@property (nonatomic, assign) NSInteger itemNumber;
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSString *> *itemViewClass;
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSMutableArray *> *itemViews;
@end
@implementation MJGridView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.insets = UIEdgeInsetsZero;
        self.rowSpacing = 0;
        self.columnSpacing = 0;
        self.column = 1;
        self.rowHeight = 0;
        //self.type = MJGridViewTypePlain;
    }
    return self;
}
- (CGSize)intrinsicContentSize {
    NSArray *subviews = [self.subviews filter:^BOOL(UIView *obj) {
        return obj.identifier.length > 0;
    }];
    CGFloat width = 0;
    CGFloat height = 0;
    for (UIView *item in subviews) {
        width = MAX(width, CGRectGetMaxX(item.frame));
        height = MAX(height, CGRectGetMaxY(item.frame));
    }
    //return CGSizeMake(width+_insets.right, height+_insets.bottom);
    CGFloat w = CGRectGetWidth(self.bounds);
    CGFloat h = height>0 ? height+_insets.bottom : height;
    return CGSizeMake(w, h);
}
- (void)layoutSubviews {
    [super layoutSubviews];
    
    NSArray *subviews = [self.subviews filter:^BOOL(UIView *obj) {
        return obj.identifier.length > 0;
    }];
    
    CGFloat width = CGRectGetWidth(self.bounds);
    CGFloat height = CGRectGetHeight(self.bounds);
    NSInteger row = ceil(1.0*subviews.count/_column);
    CGFloat itemWidth = (width-_insets.left-_insets.right-_columnSpacing*(_column-1))/_column;
    CGFloat itemHeight = _rowHeight == 0 ? (height-_insets.top-_insets.bottom-_rowSpacing*(row-1))/row : _rowHeight;
    for (int i=0; i<subviews.count; i++) {
        UIView *view = subviews[i];
        view.frame = CGRectMake(_insets.left+itemWidth*(i%_column)+_columnSpacing*(i%_column), _insets.top+itemHeight*floor(1.0*i/_column)+_rowSpacing*floor(1.0*i/_column), itemWidth, itemHeight);
    }
    [self invalidateIntrinsicContentSize];
}
- (void)didMoveToSuperview {
    [self reloadData];
}

- (void)registerView:(NSString *)className identifier:(NSString *)identifier {
    [self.itemViewClass setValue:className forKey:identifier];
}

- (UIView *)dequeueItemWithIdentifier:(NSString *)identifier {
    UIView *item = nil;
    NSMutableArray *views = self.itemViews[identifier];
    item = views.lastObject;
    if (item) {
        [views removeLastObject];
    } else {
        item = [NSClassFromString(_itemViewClass[identifier]) new];
    }
    item.identifier = identifier;
    return item;
}
- (void)reloadData {
    NSArray *subviews = [self.subviews filter:^BOOL(UIView *obj) {
        return obj.identifier.length > 0;
    }];
    for (UIView *item in subviews) {
        NSString *identifier = item.identifier;
        if (identifier.length > 0) {
            NSMutableArray *arr = _itemViews[identifier];
            if (!arr) {
                arr = [NSMutableArray array];
                [_itemViews setValue:arr forKey:identifier];
            }
            [arr addObject:item];
            [item removeFromSuperview];
        }
        
    }
    
    _itemNumber = self.number();
//    _itemNumber = [self number:<#^NSInteger(void)block#>]
    for (int i=0; i<_itemNumber; i++) {
        UIView *view = self.itemView(self, i);
        [self addSubview:view];
        // 布局
    }
    
    // 重新添加其他视图
    subviews = [self.subviews filter:^BOOL(UIView *obj) {
        return obj.identifier.length == 0;
    }];
    for (UIView *v in subviews) {
        [self addSubview:v];
    }
}

- (NSMutableDictionary<NSString *,NSString *> *)itemViewClass {
    if (!_itemViewClass) {
        _itemViewClass = [NSMutableDictionary dictionary];
    }
    return _itemViewClass;
}
- (NSMutableDictionary<NSString *,NSMutableArray *> *)itemViews {
    if (!_itemViews) {
        _itemViews = [NSMutableDictionary dictionary];
    }
    return _itemViews;
}

@end
